namespace OpenComposite.EII.RepositoryUIs
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Data;
	using System.Drawing;
	using System.IO;
	using System.Text;
	using System.Windows.Forms;
	using System.Xml;
	using System.Xml.Schema;

	using OpenComposite.EII.Repository;

	using OpenComposite.Repository.Properties;
	using System.Diagnostics;
	using System.Collections;

	public partial class UCBObject : RepositoryItemUI
	{
		#region Initialization

		public UCBObject(IServiceProvider serviceProvider)
			: base(serviceProvider)
		{
			InitializeComponent();

			init();

			this.ExcludedFromReadOnlyControls.Add(btnShowSchema);
			this.ExcludedFromReadOnlyControls.Add(btnShowCode);
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		public override IRepositoryItem RepositoryItem
		{
			get
			{
				save();
				return _bobject;
			}
			set
			{
				base.RepositoryItem = value;
				if ( value is BusinessObject ) {
					if ( _bobject != null ) {
						_bobject.ItemChanged -= _bobject_ItemChanged;
					}
					_bobject = (BusinessObject)value;
					if ( _bobject != null ) {
						_bobject.ItemChanged += new OpenComposite.EII.Services.RepositoryChangedEventHandler(_bobject_ItemChanged);
					}
					load();
				}
			}
		}

		public override string TypeDescription
		{
			get { return ""; }
		}

		public override string TypeText
		{
			get { return Resources.sBObject; }
		}

		#endregion Properties

		#endregion Public Members

		#region Protected Members

		#region Methods

		protected override void NotifyPropertyChange(string property, object value)
		{
			if ( property == "Name" && value != null ) {
				txtBObjName.Text = value.ToString();
			}
		}

		#endregion Methods

		#endregion Protected Members

		#region Private Members

		#region Fields

		private BusinessObject _bobject;

		#endregion Fields

		#region Event Handlers

		void _bobject_ItemChanged(object sender, OpenComposite.EII.Services.RepositoryChangedEventArgs e)
		{
			if ( e.Member != null && e.Member.Name == "Name" && e.NewValue != null ) {
				txtBObjName.Text = e.NewValue.ToString();
			}
			if ( tabControl1.SelectedTab == tabUses &&
				 ( e.Member != null && ( e.Member.Name == "Save" ) ) ) {
				refreshSchema();
			}
		}

		private void btnLoadSchema_Click(object sender, EventArgs e)
		{
			if ( openSchema.ShowDialog() == DialogResult.OK ) {
				using ( FileStream fs = new FileStream(openSchema.FileName, FileMode.Open) ) {
					XmlSchema xsd = XmlSchema.Read(fs,
						delegate(object s, ValidationEventArgs ve)
						{
							MessageBox.Show(ve.Message, ve.Exception.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
						});
					Helpers.ReadSchema(xsd, this._bobject);
				}
			}
			showSchema(_bobject.Schema);
		}

		private void btnRemoveSchema_Click(object sender, EventArgs e)
		{
			_bobject.Schema = null;
			showSchema(null);
		}

		private void btnShowCode_Click(object sender, EventArgs e)
		{
			_bobject.ShowBusinessObjectCode();
		}

		private void btnShowSchema_Click(object sender, EventArgs e)
		{
			if ( _bobject.Schema == null ) return;

			XmlDocument xd = new XmlDocument();
			using ( StringWriter sw = new StringWriter() ) {
				_bobject.Schema.Write(sw);
				xd.LoadXml(sw.ToString());
			}
			formXmlViewer XmlViewer = new formXmlViewer();
			XmlViewer.XmlDocument = xd;
			XmlViewer.Text = "XML-Schema of Business Object \"" + _bobject.Name + "\"";
			XmlViewer.ShowDialog();
		}

		private void tabControl1_Selected(object sender, TabControlEventArgs e)
		{
			if ( e.TabPage == tabUsedBy ) {
				usedByHierarchyBO.RepositoryItem = this.RepositoryItem as RepositoryItemBaseEx;
			} else if ( e.TabPage == tabUses ) {
				refreshSchema();
			}
		}

		private void txtBObjName_KeyPress(object sender, KeyPressEventArgs e)
		{
			if ( e.KeyChar < (char)32 ) return;
			e.Handled = !Helpers.IsValidCharForName(e.KeyChar);
		}

		#endregion Event Handlers

		#region Methods

		private void init()
		{
			_bobject = null;
		}

		private void load()
		{
			if ( _bobject == null )
				throw new NullReferenceException("No business object defined.");

			txtBObjName.Text = _bobject.Name;
			txtBObjDesc.Text = _bobject.Description;

			//tvBObject.BeginUpdate();
			//try {
			//    tvBObject.BusinessObject = null;
			//    tvBObject.BusinessObject = _bobject;
			//    tvBObject.ExpandAll();
			//} finally {
			//    tvBObject.EndUpdate();
			//}
			btnRemoveSchema.Enabled = ( _bobject.Schema != null && _bobject.BusinessObjectFields.Count == 0 );
			btnShowSchema.Enabled = ( _bobject.Schema != null );

			txtBObjName.Focus();
			txtBObjName.SelectAll();

			if ( tabControl1.SelectedTab == tabUsedBy ) {
				usedByHierarchyBO.RepositoryItem = this.RepositoryItem as RepositoryItemBaseEx;
			}
		}

		private void refreshSchema()
		{
			tvBObject.BeginUpdate();
			tvBObject.BusinessObject = null;
			tvBObject.BusinessObject = _bobject;
			tvBObject.ExpandAll();
			if ( tvBObject.Nodes.Count > 0 ) {
				tvBObject.SelectedNode = tvBObject.Nodes[0];
				tvBObject.Nodes[0].EnsureVisible();
			}
			tvBObject.EndUpdate();
		}

		private void save()
		{
			if ( _bobject == null )
				_bobject = new BusinessObject();

			_bobject.Reload();

			_bobject.Name = txtBObjName.Text;
			_bobject.Description = txtBObjDesc.Text;
			_bobject.Save();
		}

		private void showSchema(XmlSchema xsd)
		{
			btnRemoveSchema.Enabled = ( xsd != null );
			btnShowSchema.Enabled = ( xsd != null );
			tvBObject.BusinessObject = _bobject;
		}

		#endregion Methods

		#endregion Private Members
	}
}